package hehe.helper;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 反射帮助类
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class ReflectHelper
{
    /**
     * 类属性对象列表
     *<B>说明：</B>
     *<pre>
     * 缓存类属性对象
     *</pre>
     */
    protected static HashMap<String,Field> fields = new HashMap<>();

    /**
     * 类对应的 class 对象列表
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    protected static HashMap<String,List<Class>> clazzs = new HashMap<>();

    /**
     * 设置对象属性
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static void setAttribute(Object obj,Map<String,Object> attrs)
    {
        Class clazz = obj.getClass();

        for (Map.Entry<String, Object> attr : attrs.entrySet()) {
            try {
                Field field = getField(clazz,attr.getKey());
                if (field != null) {
                    field.setAccessible(true);
                    // value类型转换
                    //Object value = Format.invoke(field.getType().getTypeName(),attr.getValue(),field);
                    field.set(obj,attr.getValue());
                }
            } catch (Exception e) {
                // 不做任何事情
                e.printStackTrace();
            }
        }
    }


    /**
     * 获取对象属性
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param className class 对象
     * @param fieldName 属性名
     * @return 属性对象
     */
    public static Field getField(Class className, String fieldName)
    {
        String fieldKey = className.getName() + "." + fieldName;

        if (fields.containsKey(fieldKey)) {
            return fields.get(fieldKey);
        }

        // 读取所有父类及本来
        List<Class> superClasss = getAllClass(className);
        Field field = null ;
        for (int i = 0;i < superClasss.size();i++)  {
            field = getDeclaredField(superClasss.get(i),fieldName);
            if (field != null) {
                // 找到属性,保持至至缓存
                break;
            }
        }

        if (field != null) {
            fields.put(fieldKey,field);
        }

        return field;
    }

    /**
     * 获取类属性对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param className class 对象
     * @param attrName 属性名
     */
    public static Field getDeclaredField(Class className, String attrName)
    {

        Field field = null ;

        try {
            field = className.getDeclaredField(attrName) ;
            return field ;
        } catch (Exception e) {
            // 找不到属性
            return null;
        }
    }

    /**
     * 获取所有父类包括自己
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param targetClass
     */
    public static List<Class> getAllClass(Class targetClass)
    {

        if (clazzs.containsKey(targetClass.getName())) {
            return clazzs.get(targetClass.getName());
        }

        List<Class> superClasss = new ArrayList<>();
        superClasss.add(targetClass);

        while (true) {//当父类为null的时候说明到达了最上层的父类(Object类).
            targetClass = targetClass.getSuperclass(); //得到父类,然后赋给自己
            if (targetClass != null && !targetClass.getSimpleName().equals("Object")) {
                superClasss.add(targetClass);
            } else {
                break;
            }
        }

        clazzs.put(targetClass.getName(),superClasss);

        return superClasss;
    }

}
